import SparkMD5 from "spark-md5";

export class FileUtils {

  static async fileToMd5(file: File): Promise<string> {
    return new Promise(resolve => {
      // 使用sparkMD5的ArrayBuffer类，读取二进制文件
      const spark = new SparkMD5.ArrayBuffer()
      const fileReader = new FileReader()
      // 异步操作，读完后的结果
      fileReader.onload = (e) => {
        // 把文件开始传入spark
        spark.append(e.target.result)
        // spark计算出MD5后的结果
        const _md5 = spark.end()
        resolve(_md5)
        // 下面可以写一些自己需要的业务代码, 例如 fileItem.fileMD5 = _md5
      }
      // fileReader读取二进制文件
      fileReader.readAsArrayBuffer(file)
    })
  }

  static fileDownloadByRes(res) {
    const head = res.headers['content-disposition'] as string
    const fileName = head
      .split(';')
      .find(i => {
        return i.includes('filename')
      })
      ?.split('=')[1] || ''
    FileUtils.fileDownload([res.data] as BlobPart[], decodeURIComponent(fileName))
  }

  static fileDownload(data: BlobPart[], fileName: string) {
    const uri = window.URL.createObjectURL(new Blob(data))
    FileUtils.fileDownLoadFromUrl(uri, fileName)
    window.URL.revokeObjectURL(uri) // 释放掉blob对象
  }

  static fileDownLoadFromUrl(path: string, fileName: string) {
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = path
    document.body.appendChild(link)
    link.setAttribute('download', fileName)
    link.target = '_blank'
    link.click()
    document.body.removeChild(link) // 下载完成移除元素
  }

  static base642Blob(base64: string): Blob {
    let arr = base64.split(","),
      mime = arr[0].match(/:(.*?);/)[1], //获取前面的类型
      bstr = atob(arr[1]), // 获取后面内容
      n = bstr.length,
      u8arr = new Uint8Array(n); // 这里好像都是Uint8Array这个类型, 但不是太懂希望大佬告知
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type: mime});
  }

  static blob2File(blob: Blob, fileName: string): File {
    // @ts-ignore
    blob.lastModifiedDate = new Date(); // 文件最后的修改日期
    // @ts-ignore
    blob.name = fileName; // 文件名
    return new File([blob], fileName, {
      type: blob.type,
      lastModified: Date.now()
    });
  }

  static blob2ArrayBuffer(blob: Blob) {
    return new Promise<ArrayBuffer>((resolve, reject) => {
      const reader = new FileReader();
      reader.onerror = reject;
      reader.onload = () => {
        resolve(reader.result as ArrayBuffer);
      };
      reader.readAsArrayBuffer(blob);
    });
  }

  static blob2Base64(blob: Blob) {
    return new Promise<string>((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = () => {
        const base64 = reader.result as string;
        resolve(base64);
      }
      reader.onerror = error => reject(error);
    });
  }


  static formatFileSize(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
  }
}
